/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package utilities;

import utilities.entities.SCalendar;
import utilities.entities.DateRange;
import bdl.MatchBean;
import bdl.UtilityBean;
import entities.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Vector;
import matpred.CalendarPanel;
import matpred.SearchPanel;
import matpred.search.Search;
import utilities.entities.Result;
import utilities.entities.Result.*;

/**
 *
 * @author olawale
 */
public class PredictionSearch {
    
    private SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy");
    private SCalendar defCal = CalendarPanel.getCalendarPanel().getDefaultCalendar();
    private Search[] sp = SearchPanel.getSearchPanel().getSearchVar();

    public List<Result> analyze(){
        System.out.println("SEARCH STARTED....");
        ArrayList<Match> cm = (ArrayList) sp[0].getValues();
        List<Result> result = null;
        for(int i = 0; i < cm.size(); i++){ // for each current currentMatch
            System.out.println(">> current match: " + cm.get(i));
            Match currentMatch = cm.get(i);
            result = search(currentMatch);
        }
        System.out.println("SEARCH STOPPED....");
        return result;
    }
    
    private List<Result> search(Match currentMatch){
        ArrayList<AResult> aresult = asearch(currentMatch);
        ArrayList<BResult> bresult;
        ArrayList<Result> results = new ArrayList();
        if(aresult != null && !aresult.isEmpty()){
            for(AResult ar : aresult){
                bresult = bsearch(ar);
                if(bresult != null && !bresult.isEmpty()){
                    for(BResult br : bresult){
                        Result result = new Result(ar, br);
                        result.acResults = scoreCompare(ar.rmatch.getFixture());
                        result.bcResults = scoreCompare(br.rmatch.getFixture());
                        result.addResult = nsearch(ar.rmatch, ar.calander);
                        result.minusResult = nsearch(ar.rmatch, ar.calander, 1);
                        result.cMatch = currentMatch;

//                        UResult uresult = unsearch(currentMatch);
//                        result.uResult = uresult;
                        result.dCalendar = defCal;
                        result.pCalendar = result.aResult.calander;
                        result.prediction = UtilityBean.insertPrediction(currentMatch,
                                result.aResult.pmatch.getScores());
                        result.refNo = result.prediction.getId();
                        result.fileName = "PR" + result.refNo + ".ser";
                        Store.store(result);

                        results.add(result);
                    }
                }
            }
        }
        System.out.println("TOTAL RESULTS FOUND  = " + results.size());
        return results;
    }

    private ArrayList<AResult> asearch(Match currentMatch){
        ArrayList<AResult> result = new ArrayList();
        ArrayList<DateRange> bRange = (ArrayList) sp[4].getValues();
        if(bRange.isEmpty()) return null;
        Date [] bDate = bRange.get(0).getDates();
        List<Match> prevMatches = MatchBean.getPrevMatches(currentMatch, bDate[0], bDate[1]);
        for(Match pm : prevMatches){ //for all the previous currentMatch sdate found
            System.out.println(">> Prev. Match: " + pm.getMatchDate());
            String mdate = sdf.format(pm.getMatchDate());

            //SIDE A SEARCH
            List<SCalendar> icList = getImpCalendars();
            for(SCalendar cal : icList){
                int row = cal.findRow(mdate);
                System.out.println(" row number = " + row);
                if(row > -1){ //if the sdate is present
                    ArrayList<DateRange> aRange = (ArrayList) sp[3].getValues();//side A sdate range
                    if(aRange.isEmpty()) break;
                    for(int k = 0; k < aRange.size(); k++){ // for each side A sdate range
                        System.out.println(">> side a date range name: " + aRange.get(k).range());
                        String asd = aRange.get(k).getStartDate();
                        String aed = aRange.get(k).getEndDate();
                        List<RowMatch> resList = Utility.compare(cal, asd, aed, row);

                        for(RowMatch mrow : resList){
                            System.out.println(mrow.row);
                            String resDate = cal.getDate(mrow.row);
                            Vector resultRow = cal.getRow(mrow.row);
                            Vector defaultRow = defCal.getRow(resDate);
                            List<Match> resMatches = MatchBean.getMatches(Utility.parseDate(resDate), currentMatch.getFixture());
                            for(Match rMatch : resMatches){
                                System.out.println(rMatch);
                                Result.AResult ar = new Result().new AResult();
                                ar.pmatch = pm;
                                ar.rmatch = rMatch;
//                                ar.resultDate = resDate;
                                ar.resultRow = resultRow;
                                ar.defaultRow = defaultRow;
                                ar.calander = cal;
                                ar.arange = aRange.get(k);
                                ar.rowMatching = mrow;
                                
                                result.add(ar);
                            }

                        }
                    }
                }
            }
        }
        return result;
    }

    private ArrayList<BResult> bsearch(Result.AResult ar){
        System.out.println(">>>SIDE B SEARCH");
        System.out.println("aresult = " + ar.rmatch.getMatchDate() + " " + ar.rmatch);
        ArrayList<BResult> result = new ArrayList();
        ArrayList<DateRange> cRange = (ArrayList) sp[5].getValues();
        Match pMatch = ar.pmatch;
        SCalendar cal = ar.calander;
        int start = cal.findRow(pMatch.getMatchDate());
        Object [] levels = (Object[]) sp[10].getValues();
        int upLevel = Integer.parseInt(levels[0].toString());
        int downLevel = Integer.parseInt(levels[1].toString());
//        System.out.println("ulevel = " + upLevel + " dlevel = " + downLevel);

        int startRow = ((start - upLevel) < 0) ? 0 : (start - upLevel);
        int endRow = ((start + downLevel) > cal.getRowCount()) ? (cal.getRowCount()) : (start + downLevel);
        String startDate = cal.getDate(startRow);
        String endDate = cal.getDate(endRow);

        for(int c = 0; c < cRange.size(); c++){
            String csd = cRange.get(c).getStartDate();
            String ced = cRange.get(c).getEndDate();
            int sr = cal.findRow(csd);
            int er = cal.findRow(ced);
            List<RowMatch> tlist = new ArrayList();
            for(int r = sr; r <= er; r++){
                System.out.println("------ " + cal.getDate(r));
                tlist = Utility.compare(cal, startDate, endDate, r);
                
                for(RowMatch rm : tlist){
                    List<Match> resMatches = MatchBean.getMatches(Utility.parseDate(rm.sdate), ar.pmatch.getFixture());
                    if(resMatches != null || !resMatches.isEmpty()){
                        for(Match rMatch : resMatches){
                            Result.BResult br = new Result().new BResult();
                            System.out.println("result = " + rMatch + " " + rMatch.getScores() + " " + rm.sdate);
                            int serA = Integer.parseInt(cal.getSerial(ar.rmatch.getMatchDate()));
                            int serB = Integer.parseInt(cal.getSerial(rm.sdate));
                            br.prCode = serA - serB;
                            br.rowMatching = rm;
                            br.rmatch = rMatch;
                            br.sLocation = (rm.row < start) ? "downwards" : "upward";
                            if(rm.row == start) br.sLocation = "middle";
                            if(rm.row < start){
                                br.sDirection = "decision";
                            }else{
                                br.sDirection = "middle";
                            }

                            result.add(br);
                        }
                    }
                }
            }
        }
        return result;
    }

//    public UResult unsearch(Match currentMatch){
//        ArrayList<DateRange> uRange = (ArrayList) sp[6].getValues();
//        List<Vector> resultRows = new ArrayList();
//        List<Match> resultMatches = new ArrayList();
//
//        for(DateRange dateRange : uRange){
//            Date [] date = dateRange.getDates();
//            List<Match> prevMatches = MatchBean.getPrevMatches(currentMatch, date[0], date[1]);
//
//            for(Match pm : prevMatches){
//                String mdate = sdf.format(pm.getMatchDate());
//                Vector resultRow = defCal.getRow(mdate);
//                resultMatches.add(pm);
//                resultRows.add(resultRow);
//            }
//        }
//
//        Result.UResult uresult = new Result().new UResult();
//        return uresult;
//    }

    public List<NResult> nsearch(Match match, SCalendar calendar){
        Object [] nranges = (Object[]) sp[9].getValues();
        int serial = Integer.parseInt(calendar.getSerial(match.getMatchDate()));
        List<NResult> results = new ArrayList();

        for(Object range : nranges){
            for(int number : Utility.getNumbers(range.toString())){
                int aser = serial + number;
                Date adate = Utility.parseDate(calendar.getDate(aser));
                List<Match> amatch = MatchBean.getMatches(adate, match.getFixture());
                Vector arow = calendar.getRow(aser);
                if(amatch != null && !amatch.isEmpty()){
                    for(Match m : amatch){
                        Result.NResult nresult = new Result().new NResult();
                        nresult.rMatch = m;
                        nresult.row = arow;
                        nresult.number = number;
                        results.add(nresult);
                    }
                }
            }
        }
        return results;
    }

    public List<NResult> nsearch(Match match, SCalendar calendar, int i){
        Object [] nranges = (Object[]) sp[9].getValues();
        int serial = Integer.parseInt(calendar.getSerial(match.getMatchDate()));
        List<NResult> results = new ArrayList();

        for(Object range : nranges){
            for(int number : Utility.getNumbers(range.toString())){
                int aser = Math.abs(serial - number);
                Date adate = Utility.parseDate(calendar.getDate(aser));
                List<Match> amatch = MatchBean.getMatches(adate, match.getFixture());
                Vector arow = calendar.getRow(aser);
                if(amatch != null && !amatch.isEmpty()){
                    for(Match m : amatch){
                        Result.NResult nresult = new Result().new NResult();
                        nresult.rMatch = m;
                        nresult.row = arow;
                        nresult.number = number;
                        results.add(nresult);
                    }
                }
            }
        }
        return results;
    }

    private List<SCalendar> getImpCalendars(){
        List<SCalendar> icList = new ArrayList();
        Object [] cArrays =  (Object[]) sp[2].getValues();
        Object[] cList1 = (Object[]) cArrays[0];
        Object[] cList2 = (Object[]) cArrays[1];

        if(cList1 != null && cList2 != null){
            for(Object c1 : cList1){
                SCalendar cal1 = (SCalendar)c1;
                for(Object c2 : cList2){
                    SCalendar cal2 = (SCalendar)c2;
                    SCalendar ic = Utility.impose(cal1, cal2);
                    if(ic != null) icList.add(ic);
                }
            }
        }
        return icList;
    }

    private List<CResult> scoreCompare(int fixture){
        ArrayList<DateRange> scRange = (ArrayList) sp[8].getValues();
        if(scRange == null || scRange.isEmpty())
            return null;

        List<CResult> results = new ArrayList();
        for(DateRange dr : scRange){
            Date [] dates = dr.getDates();
            List<Match> resMatches = MatchBean.getMatches(dates[0], dates[1], fixture);
            if(resMatches != null && !resMatches.isEmpty()){
                for(Match m : resMatches){
                    Result.CResult cresult = new Result().new CResult();
                    cresult.dateRange = dr;
                    cresult.match = m;
                    results.add(cresult);
                }
            }
        }

        return results;
    }

}


